﻿using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Ast.Core.Services.Extensions;

namespace Ast.Core.Pe
{
    public class PeBinaryReader : BinaryReader
    {
        public PeBinaryReader(Stream input) : base(input)
        {
        }

        public PeBinaryReader(Stream input, Encoding encoding) : base(input, encoding)
        {
        }

        public PeBinaryReader(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen)
        {
        }

        public void SetPosition(long position)
        {
            BaseStream.Seek(position, SeekOrigin.Begin);
        }

        public T ReadAs<T>()
        {
            var size = Marshal.SizeOf<T>();
            var buffer = ReadBytes(size);
            return buffer.ReadAs<T>();
        }

        public T[] ReadArrayAs<T>(int length)
        {
            var retVal = new List<T>(length);
            for (var i = 0; i < length; i++)
            {
                var val = ReadAs<T>();
                retVal.Add(val);
            }
            return retVal.ToArray();
        }

        public T[] ReadArrayAs<T>()
        {
            var retVal = new List<T>();
            for (var i = 0;; i++)
            {
                var val = ReadAs<T>();
                if (val.Equals(default(T)))
                {
                    break;
                }
                retVal.Add(val);
            }
            return retVal.ToArray();
        }

        public string ReadAsString()
        {
            var sb = new StringBuilder();
            for (var c = ReadChar(); c != '\0'; c = ReadChar())
            {
                sb.Append(c);
            }
            return sb.ToString();
        }
    }
}